package it.softphone.commons.service.scripting;


import it.softphone.commons.service.ServiceObjectFactory;

import javax.script.ScriptException;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.SystemConfiguration;

/**
 * NON SINGLETON factory that create a new scripting service. 
 * 
 * @author softphone
 *
 */
public abstract class ScriptingServiceFactory {

	/**
	 * 
	 * abstract factory method. This method must be implemented if you have to create a new script service implementation
	 * 
	 * @param conf
	 * @return
	 * @throws ScriptException
	 */
	public abstract ScriptingService newScriptingService( Configuration conf ) throws ScriptException;
	
	/**
	 * System variable name that should contain FQN of the service implementation
	 */
	public static final String SERVICE_SCRIPTING_PROPERTY = "it.softphone.commons.service.scripting";

	/**
     * 
     * Lookup for a SPI implementation or system variable 'it.softphone.commons.service.scripting' otherwise return default implementation
     * 
     * @param conf configuration for service initialization
     * @return new scripting service instance 
	 * @throws ScriptException 
	 * @see ScriptingServiceDefaultImpl
     */
    public static synchronized ScriptingService getScriptingService( Configuration conf ) throws ScriptException  {
        
    	ScriptingServiceFactory result = null;
    	
    	try {
    		result = ServiceObjectFactory.getSPIService(ScriptingServiceFactory.class);
    		
		} catch (Exception e) {
			throw new ScriptException(e);
		}

		if( result==null ) {
	    	try {
				result =  ServiceObjectFactory.getService(SERVICE_SCRIPTING_PROPERTY, DefaultFactory.class);
			} catch (Exception e) {
				throw new ScriptException(e);
			}
		}
		
		ScriptingService service =  result.newScriptingService(conf.subset("script"));
		
		return service;
    } 

    /**
     * 
     * Lookup for a SPI implementation or system variable 'it.softphone.commons.service.scripting' otherwise return default implementation
     * 
     * @return new scripting service instance 
	 * @throws ScriptException 
	 * @see ScriptingServiceDefaultImpl
     */
    public static synchronized ScriptingService getScriptingService() throws ScriptException  {
    	return getScriptingService( new SystemConfiguration() );
    }
    
    /**
     * Default Script service Factory
     * 
     * @author softphone
     *
     */
    public static class DefaultFactory extends ScriptingServiceFactory {

		@Override
		public ScriptingService newScriptingService(Configuration conf) throws ScriptException {
			return new ScriptingServiceDefaultImpl(conf);
		}
    
    }
}
